<template>
    <div class="resourcesTable">
        <div class="">
            <el-divider class="topLine"><i class="lineIcon el-icon-document-copy"></i><span
                    class="lineTitle">模块-权限资源管理表列表</span></el-divider>
        </div>
        <el-col :span="8">

            <el-card class="box-card">
                <div slot="header" class="clearfix">
                    <el-tag class="boxCardTitle" effect="plain">JSON资源管理</el-tag>
                    <el-button class="boxCardTitleDesc" type="text">JSON文本传输助手</el-button>
                    <!--<span class="boxCardTitleIcon glyphicon glyphicon-retweet"></span>-->
                </div>
                <el-input
                        type="textarea"
                        :rows="20"
                        placeholder="请输入内容"
                        v-model="resourcesJson">
                </el-input>
                <el-button class="resourceBtn" type="primary" @click="saveJSON">一键生成菜单</el-button>
            </el-card>

        </el-col>
        <el-col :span="8">
            <div class="switchDrag">
                <!--绑定switchDraggable参数，默认false，点击拖拽，显示批量保存-->
                <el-switch class="switchDragChoose"
                           v-model="switchDraggable"
                           active-text="开启批量删除"
                           inactive-text="关闭批量删除">
                </el-switch>
                <el-button type="primary" class="switchDragBtn" @click="addResource">新增主菜单</el-button>
                <el-button v-if="switchDraggable" type="danger" class="switchDragBtn" @click="batchDel">批量删除</el-button>
            </div>
            <div class="categoryTree">

                <!--绑定data中的categorys
                :props绑定传入的参数及名称
                :expand-on-click="false"取消点击行收缩/展开子分类，只有点击箭头时展开
                @node-click:节点点击事件
                show-checkbox：显示选择框
                node-key：做整个树状结构的唯一标识，对应后端sql的uniId
                default-expand-all：默认展开全部节点
                default-expand-keys：默认展开的节点的数组
                draggable：开启拖拽
                :allow-drop:判断目标节点能否被放置 Function(draggingNode, dropNode, type)
                @node-drop：拖拽成功时，触发的事件。被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
                |- type='prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后

                ref=""为tree起别名，用于批量删除
                |-(leafOnly, includeHalfChecked) 接收两个 boolean 类型的参数
                    1. 是否只是叶子节点，默认值为 false
                    2. 是否包含半选节点，默认值为 false
                    注意：传入一个数组

                --》设置4级分类：3级分类显示append，4级分类显示remove
                |-add判定：绑定level属性，sql中默认属性
                |-remove判定
                  A：可以使用绑定的node属性，获取子节点信息的属性名=childNodes --》 v-if="node.level<=3"
                     node中的parent包含父节点信息data：node-》parent-》data-》list[0]-》uniId，用于展开之前操作元素的父级菜单
                  B：可以使用绑定的data属性，获取子节点信息的属性名=children   --》 v-if="node.childNodes.length===0"

                -->

                <el-tree
                        :data="resourcess"
                        :props="defaultProps"
                        :expand-on-click-node="false"
                        node-key="uniId"
                        show-checkbox
                        :default-expanded-keys="expendedKeys"
                        ref="resourcesTree">
                <span class="tree-node" slot-scope="{node,data}">
                    <span class="nodeIcon glyphicon glyphicon-folder-open"></span>
                    <span class="labelName">{{node.label}}</span>
                    <span class="option-btn">
                    <el-button class="opt-btn-add" icon="el-icon-circle-plus" v-if="node.level<=3" type="primary"
                               size="mini" @click="() => append(data)" plain>新增</el-button>
                    <el-button class="opt-btn-edit" icon="el-icon-question"
                               type="primary"
                               size="mini" @click="() => edit(data)" plain>修改</el-button>
                    <el-button class="opt-btn-del" icon="el-icon-remove" v-if="node.childNodes.length===0"
                               type="primary" size="mini" @click="() => del(node,data)" plain>刪除</el-button>
                    </span>
                </span>

                </el-tree>
            </div>
            <!--:data绑定data中预设的参数
                单行显示:show-overflow-tooltip="true"
                如果为tr，则需要v-for="(resources,index) of resourcess" :key="index"
                table有间隔，将可放大的table不设置width宽度
            -->
            <!--<el-table
                    ref="multipleTable"
                    tooltip-effect="dark"
                    @selection-change="handleSelectionChange"
                    :data="resourcess"
                    :show-overflow-tooltip="true"
                    border
                    style="width: 100%"
                    class="previous-row"
                    :header-cell-style="{backgroundImage:'linear-gradient(#ff6e02,#ff6d00)',color:'#ffffff',}"
            >

                <el-table-column type="selection" width="35">
                </el-table-column>
                <el-table-column
                        sortable
                        fixed
                        prop="uniId"
                        label="ID"
                        width="70"
                        :show-overflow-tooltip="true"
                >
                </el-table-column>

                <el-table-column
                        sortable
                        fixed
                        prop="name"
                        label="资源名称"
                        width="100"
                        :show-overflow-tooltip="true"
                >
                </el-table-column>

                <el-table-column
                        sortable
                        fixed
                        prop="page"
                        label="拦截页面"
                        width="200"
                        :show-overflow-tooltip="true"
                >
                </el-table-column>

                <el-table-column
                        sortable
                        fixed
                        prop="request"
                        label="请求"

                        :show-overflow-tooltip="true"
                >
                </el-table-column>

                <el-table-column
                        sortable
                        fixed
                        prop="parent"
                        label="父ID"
                        width="70"
                        :show-overflow-tooltip="true"
                >
                </el-table-column>

                <el-table-column
                        class="optionList"
                        fixed="right"
                        label="操作"
                        width="150">
                    &lt;!&ndash;使用slot-scope传递当前行参数&ndash;&gt;
                    <template slot-scope="scope">
                        <el-button
                                size="mini"
                                type="primary"
                                @click="edit(scope.row)">编辑
                        </el-button>
                        &lt;!&ndash;<el-button
                                size="mini"
                                type="warning"
                                @click="del">排序
                        </el-button>&ndash;&gt;
                        <el-button
                                size="mini"
                                type="danger"
                                @click="del(scope.row)">删除
                        </el-button>
                    </template>

                </el-table-column>
            </el-table>-->


            <!--<div class="pageHelper">
                <el-button class="flushBTN" type="primary" @click="pageList(1)">刷新数据</el-button>
                <page-helper ref="pageHelper" :list="pageList"></page-helper>

            </div>-->

        </el-col>

        <!--
        :visible.sync ：接收一个boolean布尔值，true时显示
        -->
        <div class="dialogModal">
            <el-dialog
                    :title="dialogTitle"
                    :visible.sync="dialogVisible"
                    width="30%"
                    :close-on-click-modal="false"
            >
                <el-form :model="resources" ref="resources" :rules="rules">
                    <el-form-item label="资源名称">
                        <el-input v-model="resources.name" autocomplete="off"></el-input>
                    </el-form-item>
                    <el-form-item label="排序">
                        <el-input v-model="resources.sort" autocomplete="off"
                                  :disabled="resources.sort!=null?false:true"></el-input>
                    </el-form-item>
                    <el-form-item label="资源页">
                        <el-input v-model="resources.page" autocomplete="off"></el-input>
                    </el-form-item>
                    <el-form-item label="请求路径">
                        <el-input type="textarea" v-model="resources.request" autocomplete="off"></el-input>
                    </el-form-item>
                </el-form>

                <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="save('resources')">确 定</el-button>
                </span>
            </el-dialog>

        </div>
    </div>
</template>

<script>
    //import PageHelper from "../../../components/PageHelper";

    export default {
        name: "ResourcesSet",
        //引用组件
        //components: {PageHelper},
        data() {
            let nameValidate = (rule, value, callback) => {
                function getLength(str) {
                    //如果为中文，替换为ccc，1个中文字符计算长度=1
                    return str.replace(/[^x00-xff]/g, 'c').length;
                }

                if (value === '') {
                    callback(new Error("资源名称不能为空"));
                } else if (getLength(value) < 2) {
                    callback(new Error("资源名称长度至少3位"));
                } else {
                    callback();
                }
            };
            return {
                message: '这里是大模块-权限资源管理表内容页',
                resourcess: [],
                resources: {},
                resourcesJson: '',
                //tree
                rules: {
                    name: [
                        {validator: nameValidate, trigger: 'blur'}
                    ],
                },
                expendedKeys: [], //tree默认展开的数组
                dialogVisible: false, //对话框显示，默认为false
                defaultProps: {
                    children: 'children', //子菜单的属性名
                    label: 'name' //显示的名称
                },
                dialogType: "", //对话框类型：添加add/更新edit
                dialogTitle: "",
                maxLevel: 0, //拖拽节点的最大深度
                updateNodes: [], //存放所有拖拽后的节点位置/排序/id等
                switchDraggable: false, //绑定是否开启拖拽
                pId: [], //全局pId，批量保存为数组,
                uniIds: [], //批量删除
            }
        },
        mounted() {
            //1.普通列表查询
            //this.list();
            //自定义赋值分页每页行数
            //this.$refs.pageHelper.size = 10;
            //2.分页列表查询，默认初始化执行第一页
            //this.pageList(1);

            //3.获取tree结构
            this.resourceTreeList();
        },
        methods: {
            //多选的方法
            toggleSelection(rows) {
                if (rows) {
                    rows.forEach(row => {
                        this.$refs.multipleTable.toggleRowSelection(row);
                    });
                } else {
                    this.$refs.multipleTable.clearSelection();
                }
            },
            handleSelectionChange(val) {
                this.multipleSelection = val;
            },
            //1.list查询
            list() {
                this.$axios.get(process.env.VUE_APP_SERVER + '/system/admin/resources/dtoList')
                    .then((response) => {
                        console.log("模块-权限资源管理表列表：", response);
                    })
            },
            //2.查询当前页，需要设置变量传入pageHelper分页插件
            pageList(page) {
                Loadings.show();
                this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/pageList', {
                    currentPage: page, //向后端发送参数。当前页
                    size: this.$refs.pageHelper.size, //引用传入组件后，在标签中refs定义的别名
                }).then((response) => {
                    Loadings.hide();
                    let resp = response.data;
                    this.resourcess = resp.responseData.listPageData;
                    this.$refs.pageHelper.render(page, resp.responseData.totalSize);

                })
            },
            //tree型结构数据
            resourceTreeList() {
                Loadings.show();
                this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/dtoTree').then((response) => {
                    Loadings.hide();
                    let resp = response.data;
                    this.resourcess = resp.responseData;
                })
            },

            //新增主菜单
            addResource() {
                this.dialogType = "新增主菜单";
                this.dialogTitle = "新增主菜单资源";
                this.resources = {};
                this.dialogVisible = true;
                this.resources.sort = 0;
                this.resources.parentId = "00000000";
                /*this.$axios.get(process.env.VUE_APP_SERVER + '/system/admin/resources/getParentId')
                    .then((response) => {
                        let resp = response.data;
                        if (resp.success) {
                            console.log(resp.responseData);
                            this.resources.parentId = resp.responseData;
                        }
                    })*/

                this.resources.level = 1;
                this.resources.isShow = 1;
            },
            //批量删除
            batchDel() {
                //let uniIds = [];
                let leafName = [];
                let checkedLeaf = this.$refs.resourcesTree.getCheckedNodes();
                for (let i = 0; i < checkedLeaf.length; i++) {
                    /*注意axios只接收json和dataForm数据，如果是其他如string、[]list数据，将在前端被拦截
                    这里需要this.定义好的属性，axios自动转化为json
                    * */
                    this.uniIds.push(checkedLeaf[i].uniId);
                    leafName.push(checkedLeaf[i].name);
                }
                //let ids=JSON.stringify(uniIds);
                this.$confirm(`是否批量删除当前【${leafName}】分类？`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    //axios默认不允许传输数组
                    this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/delBatch', this.uniIds)
                        .then((response) => {
                            let resp = response.data;
                            if (resp.success) {
                                this.$message({
                                    type: 'success',
                                    message: `【${leafName}】分类删除成功！`
                                });
                                this.resourceTreeList();
                                //删除成功，展开之前的父节点
                                this.expendedKeys = this.pId;
                            }
                        })

                })
            },
            //拖拽批量保存
            /*batchDraggableSave() {
                console.log("批量保存的数组：",this.updateNodes);
                this.$axios.post(process.env.VUE_APP_SERVER + "/system/admin/resources/update/level", this.updateNodes)
                    .then((response) => {
                        let resp = response.data;
                        if (resp.success) {
                            this.$message({
                                type: 'success',
                                message: `资源顺序更新成功！`
                            });
                            console.log("更新资源：", this.updateNodes);
                            this.resourceTreeList();
                            //更新成功，展开之前的父节点数组
                            this.expendedKeys = this.pId;
                            //更新成功，初始化变量数据
                            this.updateNodes = [];
                            this.maxLevel = 0;
                            //this.pId='00000000';
                        }
                    });
            },*/
            //新增子菜单
            append(data) {
                this.dialogType = "新增分类";
                this.dialogTitle = "新增模块分类";
                this.resources = {};
                this.dialogVisible = true;
                this.resources.parentId = data.uniId;
                //这里获取到的level是data中，而这里因为点击了父节点新增子节点，如果父节点为2，那么子节点+1=3
                this.resources.sort = 0;
                this.resources.level = data.level * 1 + 1;
                this.resources.isShow = 1;
                /**对象解构：
                 * var {uniId,name,...}=this.category
                 * 发送时，直接发送解构对象的数据{uniId...}
                 */
            },
            //4.修改菜单
            edit(resources) {
                /*jquery继承对象： $.extend({新对象},旧对象)
                避免vue数据绑定漏洞，更改数据时，随之更改显示的data，但实际没有进行真实保存数据库
                 */
                this.dialogType = "更新分类";
                this.dialogTitle = "更新模块分类";
                this.dialogVisible = true;
                /*jquery继承对象： $.extend({新对象},旧对象) 如果我重新请求
               避免vue数据绑定漏洞，更改数据时，随之更改显示的data，但实际没有进行真实保存数据库
               this.module=$.extend({},module);
                */
                this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/info/' + resources.uniId)
                    .then((response) => {
                        let resp = response.data;
                        if (resp.success) {
                            this.resources = resp.responseData;
                        }
                    })

            },
            del(node, resources) {
                /**
                 * 前端=》路径内携带参数使用url：'../'+{param}
                 * 后端=》requestMapping('../{param}')
                 *       void ...(@PathVariable String {param})
                 *
                 * ***引用toast的showConfirm全局方法，需要定义局部变量_this
                 * ***并且将存入的resources转化为局部对象，才能获取到uniId
                 */
                let _this = this;
                let resourcesParam = resources;
                toast.showConfirm(resources.name, function () {
                        _this.$axios.delete(process.env.VUE_APP_SERVER + '/system/admin/resources/del/' + resourcesParam.uniId)
                            .then((response) => {

                                let resp = response.data;
                                if (resp.success) {
                                    _this.resourceTreeList();
                                    //删除成功，展开之前的父节点
                                    _this.expendedKeys = [node.parent.data.uniId];
                                }

                            })

                    }
                )
            },
            save(formName) {
                let responseMsg = '';
                //前端校验
                this.$refs[formName].validate((valid) => {
                    if (valid) {

                        this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/save', this.resources)
                            .then((response) => {
                                let resp = response.data;
                                responseMsg = response;

                                if (resp.success) {
                                    //关闭对话框
                                    this.dialogVisible = false;
                                    this.resourceTreeList();
                                    //展开父级菜单
                                    this.expendedKeys = [this.resources.parentId];
                                    toast.success("保存成功", "bottom-end");

                                } else {
                                    this.$notify({
                                        title: '填写内容错误',
                                        message: resp.responseMsg,
                                        position: "top-right",
                                        type: 'warning'
                                    });
                                }
                            })
                    } else {
                        this.$notify({
                            title: '填写内容错误',
                            message: '请按照提示内容填写正确信息',
                            position: "top-right",
                            type: 'warning'
                        });
                        return false;
                    }
                });
            },
            //批量保存：一键生成菜单
            saveJSON() {
                let responseMsg = '';
                if (Tool.isEmpty(this.resourcesJson)) {
                    toast.warning("资源内容不能为空！");
                    return;
                }
                let json = JSON.parse(this.resourcesJson);

                Loadings.show();
                //前端校验
                this.$axios.post(process.env.VUE_APP_SERVER + '/system/admin/resources/saveResources', json)
                    .then((response) => {
                        Loadings.hide();
                        let resp = response.data;
                        responseMsg = response;

                        if (resp.success) {
                            //this.pageList(1);
                            this.resourceTreeList();
                            //引入全局变量toast提示
                            toast.success("保存成功", "bottom-end");
                        } else {
                            this.$notify({
                                title: '更新失败，请联系管理员!',
                                message: resp.responseMsg,
                                position: "top-right",
                                type: 'warning'
                            });
                        }
                    });
            },

        }
    }
</script>

<style scoped>
    /*顶部line样式*/
    .topLine {
        background-color: #2a92ee;
    }

    .lineIcon {
        font-size: 22px;
        color: #2a92ee;
        position: relative;
    }

    .lineTitle {
        position: relative;
        font-size: 16px;
        color: #2a92ee;
    }

    /*table样式*/
    .previous-row {
        background: #f0f9eb;
        margin-left: 2%;
        max-width: 96%;

    }

    .optionList {
        text-align: center;
    }

    /deep/ .el-table td, .el-table th {
        padding: 5px 0;
        text-align: center;
    }

    /deep/ .el-table .cell {
        padding-right: 2px;
        line-height: 20px;
        text-align: center;

    }

    /deep/ .el-table .cell, .el-table--border td:first-child .cell, .el-table--border th:first-child .cell {
        padding-left: 5px;
    }

    /**分页位置/
     */
    .pageHelper {
        margin-left: 60px;
    }

    .flushBTN {
        position: relative;
        float: left;
        max-width: 95px;
        margin-right: 20px;
        margin-top: 5px;
    }

    /*页面分布*/

    .el-col {
        border-radius: 4px;
    }

    .bg-purple {

    }

    .bg-purple-light {

    }

    .grid-content {
        border-radius: 4px;
        min-height: 36px;
    }

    .row-bg {
        padding: 10px 0;
        background-color: #f9fafc;
    }

    /*卡片*/
    .text {
        font-size: 14px;
    }

    .item {
        margin-bottom: 18px;
    }

    .clearfix:before,
    .clearfix:after {
        display: table;
        content: "";
    }

    .clearfix:after {
        clear: both
    }

    .box-card {
        width: 100%;

    }

    /*资源*/
    .resourceBtn {
        float: right;
        margin-top: 15px;
        margin-bottom: 30px;
        margin-right: 10px;
    }

    .boxCardTitle {
        font-size: 18px;
        float: left;
        padding: 10px 20px;
        height: 100%;
    }

    .boxCardTitleDesc {
        float: left;
        margin-left: 10px;
        margin-top: 15px;

    }

    .boxCardTitleIcon {
        color: #1d7dd6;
    }

    /*树型控件*/
    /deep/ .el-tree-node__content {
        height: 30px;
    }

    .categoryTree {
        position: absolute;
        margin-top: 80px;
        float: left;
        margin-left: 20px;
    }

    .nodeIcon {
        margin-right: 15px;
        color: #2a92ee;
        font-size: 15px;
    }

    .labelName {
        margin-right: 30px;
        font-size: 15px;
    }

    .opt-btn-add {
        font-size: 13px;
        padding: 3px 6px;
        margin-right: 4px;
    }

    .opt-btn-edit {
        font-size: 13px;
        padding: 3px 6px;
        margin-right: 4px;
    }

    .opt-btn-del {
        font-size: 13px;
        padding: 3px 6px;

    }

    /*拖拽开关*/
    .switchDrag {
        margin-top: 20px;
        margin-bottom: 30px;
        position: absolute;
    }

    .switchDragChoose {
        float: left;
        font-size: 25px;
        margin-top: 8px;
        margin-left: 30px;
    }

    .switchDragBtn {
        float: left;
        margin-left: 20px;
    }
</style>